/*
 * Copyright (C) 2009,2010,2011  Paulo Cesar Pereira de Andrade.
 *
 * This is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * Authors:
 *	Paulo Cesar Pereira de Andrade
 */

#ifndef _ehashtable_h
#define _ehashtable_h

/*
 * Types
 */
struct ehashentry {
    ehashentry_t	*next;
    eint32_t		 nt;
    eint32_t		 vt;
    union {
	eint_t	 	 i;
	efloat_t	 d;
	eobject_t	 o;
	evector_t	*v;
	empz_t		 z;
	empq_t		 q;
	empr_t		 r;
	empc_t		 c;
	struct {
	    eint_t	 re;
	    eint_t	 im;
	}		 ii;	/* compare complex double as a pair of ints */
	ecdd_t		 dd;
	ecqq_t		 qq;
    } nv;
    union {
	eint_t		 i;
	efloat_t	 d;
	eobject_t	 o;
	evector_t	*v;
	empz_t		 z;
	empq_t		 q;
	empr_t		 r;
	empc_t		 c;
	ecdd_t		 dd;
	ecqq_t		 qq;
    } vv;
    eint32_t		 key;
};

struct ehashtable {
    ehashentry_t	**entries;
    eint32_t		  size;
    eint32_t		  count;
    /* temporary rehash storage */
    evector_t		 *vector;
#if HAVE_THREAD
    pthread_mutex_t	  mutex;
#endif
};

/*
 * Prototypes
 */
extern void
enew_hashtable(eobject_t *pointer, eint32_t size);

/*   must be called on a 'real' or 'fake' hashentry before calling
 * hashentry functions.
 *   'real' ones are used in calls to eput_hashentry()
 *   'fake' ones are used in calls to eget_hashentry() or erem_hashentry() */
extern void
ekey_hashentry(ehashentry_t *entry);

extern void
eput_hashentry(ehashtable_t *hash, ehashentry_t *entry);

extern ehashentry_t *
eget_hashentry(ehashtable_t *table, ehashentry_t *entry);

extern void
erem_hashentry(ehashtable_t *table, ehashentry_t *entry);

extern void
init_hashtable(void);

#endif /* _ehashtable_h */
